eFlgShiftKey	= 2
eFlgCntlKey	 = 4
eFlgMetaKey	 = 8
eFlgLeftShiftKey  = 16
eFlgRightShiftKey = 32
eFlgLeftCntlKey   = 64
eFlgRightCntlKey  = 128
eFlgLeftMetaKey   = 256
eFlgRightMetaKey  = 512

eCrsUp				= 0
eCrsDown		= 1
eCrsLeft		= 2
eCrsRight		= 3

eEvtNone		= -1

eEvtAscFirst	= 0
eEvtAscLast	 = 255

eEvtUpperFirst  = ord("A")
eEvtUpperLast   = ord("Z")
eEvtLowerFirst  = ord("a")
eEvtLowerLast   = ord("z")

eEvtPrintableFirst = ord(" ") # depends on the ascii table!!!
eEvtPrintableLast  = ord("~") # depends on the ascii table!!!

eEvtMetaFirst   = 256   # returned if key depressed with "Left" or "Right" key
eEvtMetaLast	= 512

eEvtKey_Delete  = 127
eEvtKey_Space		= 32
eEvtKey_Escape  = 27
eEvtKey_Return  = 13
eEvtKey_Enter  		= 10
eEvtKey_Tab  		= 9
eEvtKey_Backspace  = 8

eEvtKey_odiaresis = 246
eEvtKey_adiaresis = 228
eEvtKey_udiaresis = 252
eEvtKey_Odiaresis = 214
eEvtKey_Adiaresis = 196
eEvtKey_Udiaresis = 220
 
# cursor keys
eEvtFirstCursorKey= (0x7f << 8) + 43				
eEvtCursorUp	= eEvtFirstCursorKey + eCrsUp
eEvtCursorDown  = eEvtFirstCursorKey + eCrsDown
eEvtCursorLeft  = eEvtFirstCursorKey + eCrsLeft
eEvtCursorRight = eEvtFirstCursorKey + eCrsRight
eEvtLastCursorKey= eEvtCursorRight

# F1 - F64 function keys
eEvtPfkFirst	= eEvtLastCursorKey + 1
eEvtPfkLast	 = eEvtLastCursorKey + 64

# other function keys
eEvtOtherKeyFirst 	= eEvtPfkLast + 1
eEvtKey_Print		= eEvtOtherKeyFirst + 0
eEvtKey_PageUp		= eEvtOtherKeyFirst + 1
eEvtKey_PageDown 	= eEvtOtherKeyFirst + 2
eEvtKey_Home		= eEvtOtherKeyFirst + 3
eEvtKey_End			= eEvtOtherKeyFirst + 4
eEvtKey_Undo		= eEvtOtherKeyFirst + 5
eEvtKey_Redo		= eEvtOtherKeyFirst + 6
eEvtKey_Find		= eEvtOtherKeyFirst + 7
eEvtKey_Cancel		= eEvtOtherKeyFirst + 8
eEvtKey_Props		= eEvtOtherKeyFirst + 9
eEvtKey_Front		= eEvtOtherKeyFirst + 10
eEvtKey_Open		= eEvtOtherKeyFirst + 11
eEvtKey_Cut			= eEvtOtherKeyFirst + 12
eEvtKey_Copy		= eEvtOtherKeyFirst + 13
eEvtKey_Paste		= eEvtOtherKeyFirst + 14
eEvtKey_Insert		= eEvtOtherKeyFirst + 15
eEvtOtherKeyLast 	= eEvtKey_Insert + 1

eEvtKey_AnyOtherKey   = eEvtOtherKeyLast + 1

KeyMap={}
KeyMap[eEvtKey_Print]		= "Print"
KeyMap[eEvtKey_PageUp]		= "PageUp"
KeyMap[eEvtKey_PageDown]	= "PageDown"
KeyMap[eEvtKey_Home]		= "Home"
KeyMap[eEvtKey_Insert]		= "Insert"
KeyMap[eEvtKey_End]			= "End"
KeyMap[eEvtKey_Undo]		= "Undo"
KeyMap[eEvtKey_Redo]		= "Redo"
KeyMap[eEvtKey_Find]		= "Find"
KeyMap[eEvtKey_Cancel]		= "Cancel"
KeyMap[eEvtKey_Props]		= "Props"
KeyMap[eEvtKey_Front]		= "Front"
KeyMap[eEvtKey_Open]		= "Open"
KeyMap[eEvtKey_Cut]			= "Cut"
KeyMap[eEvtKey_Copy]		= "Copy"
KeyMap[eEvtKey_Paste]		= "Paste"

# this key is never generated as a 'real' key....
KeyMap[eEvtKey_AnyOtherKey]		= "AnyOtherKey"

KeyMap[eEvtCursorUp]		= "Up"
KeyMap[eEvtCursorDown]		= "Down"
KeyMap[eEvtCursorLeft]		= "Left"
KeyMap[eEvtCursorRight]		= "Right"


for i in range(eEvtPfkFirst,eEvtPfkLast):
	KeyMap[i]="F%d" % (i-eEvtPfkFirst)

for i in range(0,ord(" ")-1):
	KeyMap[i]="C-%c" % (chr(i+ord("@")))
	KeyMap[i+256]="M-C-%c" % (chr(i+ord("@")))
for i in range(ord(" "),255):
	KeyMap[i]=chr(i)
	KeyMap[i+256]="M-%c" % (chr(i))

KeyMap[eEvtKey_Escape]  = "Esc"
KeyMap[eEvtKey_Delete]  = "Del"
KeyMap[eEvtKey_Space]		= "Space"
KeyMap[eEvtKey_Backspace]  = "Backspace"
KeyMap[eEvtKey_Return]  = "Return"
KeyMap[eEvtKey_Enter]  		= "Enter"
KeyMap[eEvtKey_Tab]  		= "Tab"
 
KeyMap[eEvtKey_odiaresis]		= "odiaresis"
KeyMap[eEvtKey_adiaresis]		= "adiaresis"
KeyMap[eEvtKey_udiaresis]		= "udiaresis"
KeyMap[eEvtKey_Odiaresis]		= "Odiaresis"
KeyMap[eEvtKey_Adiaresis]		= "Adiaresis"
KeyMap[eEvtKey_Udiaresis]		= "Udiaresis"

InvKeyMap={}
for i in KeyMap.keys():
	InvKeyMap[KeyMap[i]]=i

class Token:
	def __init__(self,code,flags):
		self.code=code
		self.flags=flags

	def IsAscii(self):
		return eEvtAscFirst <= self.code <= eEvtAscLast 
	def IsUpper(self):
		return eEvtUpperFirst <= self.code <= eEvtUpperLast 
	def IsLower(self):
		return eEvtLowerFirst <= self.code <= eEvtLowerLast 
	def IsPrintable(self):
		return eEvtPrintableFirst <= self.code <= eEvtPrintableLast 
	def IsKey(self):
		return eEvtAscFirst <= self.code <= eEvtMetaLast 
	def IsFunctionKey(self):
		return eEvtPfkFirst <= self.code <= eEvtPfkLast 
	def IsOtherFunctionKey(self):
		return eEvtOtherKeyFirst <= self.code <= eEvtOtherKeyLast 
	def IsCursorKey(self):
		return eEvtFirstCursorKey <= self.code <= eEvtLastCursorKey 
	def IsShift(self):
		return self.flags & eFlgShiftKey 
	def IsLeftShift(self):
		return self.flags & eFlgLeftShiftKey 
	def IsRightShift(self):
		return self.flags & eFlgRightShiftKey 
	def IsControl(self):
		return self.flags & eFlgCntlKey 
	def IsLeftControl(self):
		return self.flags & eFlgLeftCntlKey 
	def IsRightControl(self):
		return self.flags & eFlgRightCntlKey 
	def IsMeta(self):
		return self.flags & eFlgMetaKey 
	def IsLeftMeta(self):
		return self.flags & eFlgLeftMetaKey 
	def IsRightMeta(self):
		return self.flags & eFlgRightMetaKey 
 
	def SetMeta(self):
		self.flags=self.flags | eFlgMetaKey
	def SetShift(self):
		self.flags=self.flags | eFlgShiftKey
		if self.IsLower():
			self.code=self.code - eEvtLowerFirst + eEvtUpperFirst
	def SetLeftShift(self):
		self.flags=self.flags | eFlgShiftKey | eFlgLeftShift
		if self.IsLower():
			self.code=self.code - eEvtLowerFirst + eEvtUpperFirst
	def SetRightShift(self):
		self.flags=self.flags | eFlgShiftKey | eFlgRightShift
		if self.IsLower():
			self.code=self.code - eEvtLowerFirst + eEvtUpperFirst
	def SetControl(self):
		self.flags=self.flags | eFlgCntlKey
	def SetLeftControl(self):
		self.flags=self.flags | eFlgCntlKey | eFlgLeftCntlKey
	def SetRightControl(self):
		self.flags=self.flags | eFlgCntlKey | eFlgRightCntlKey
	def SetMeta(self):
		self.flags=self.flags | eFlgMetaKey
	def SetLeftMeta(self):
		self.flags=self.flags | eFlgMetaKey | eFlgLeftMetaKey
	def SetRightMeta(self):
		self.flags=self.flags | eFlgMetaKey | eFlgRightMetaKey

	def CursorDir(self):
		return self.code - eEvtFirstCursorKey 
	def FunctionCode(self):
		return self.code - eEvtPfkFirst 

	def ASCII(self):
		if KeyMap.has_key(self.code):
			ch = KeyMap[self.code]
		else:
			ch = chr(self.code&127)
		return ch

	def KeyName(self):
		if KeyMap.has_key(self.code):
			ch = KeyMap[self.code]
		else:
			ch = chr(self.code&127)
		if self.IsShift() and not self.IsPrintable():
			ch = "S-" + ch
		if self.IsControl():
			ch = "C-" + ch
		if self.IsMeta():
			ch = "M-" + ch
		return ch

	def GetCode(self):
		return self.code
	def GetFlags(self):
		return self.flags
	def GetCodeFlags(self):
		return (self.code,self.flags)

	def Dump(self):
		if self.IsAscii():
			print "IsAscii",
		if self.IsKey():
			print "IsKey",
		if self.IsFunctionKey():
			print "IsFunctionKey",
		if self.IsOtherFunctionKey():
			print "IsOtherFunctionKey",
		if self.IsCursorKey():
			print "IsCursorKey",
		if self.IsShift():
			print "IsShift",
		if self.IsControl():
			print "IsControl",
		if self.IsMeta():
			print "IsMeta",
		print self.code, self.KeyName()



def KeyName2CodeFlags(keyname):
	flags=0
	code=0
	while 1:
		if keyname[:2] == "M-":
			flags=flags | eFlgMetaKey
			keyname=keyname[2:]
		elif keyname[:2] == "C-":
			flags=flags | eFlgCntlKey
			keyname=keyname[2:]
		elif keyname[:2] == "S-":
			flags=flags | eFlgShiftKey
			keyname=keyname[2:]
		else:
			break
	code=InvKeyMap[keyname]
	return (code,flags)

# raiase an KeyError if not a valid key...
def ValidateKeyName(keyname):
	import string
	# if we have a multiple key....
	for key in string.split(keyname):
		try:
			x=KeyName2CodeFlags(key)
		except KeyError:
			raise KeyError, "in key %s : %s is wrong" %(`keyname`,`key`)
